package worldinruin.core.imp;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;
import java.util.Set;

import worldinruin.core.IPlayer;
import worldinruin.core.ISoldier;
import worldinruin.core.ITile;
import worldinruin.core.ITroop;
import worldinruin.core.IType;
import worldinruin.core.imp.soldiers.SoldierTypes;
import worldinruin.utils.IObservable;


public class Troop implements ITroop, IObservable {
	
	private final HashMap<ISoldier, Integer> map = new HashMap<ISoldier, Integer>();
	private ITile position;
	private IType soldierType = SoldierTypes.TROOP;
	private PropertyChangeSupport pcs;
	private IPlayer player;
	
	/**
	 * Creates a new troop.
	 */
	public Troop(){
		pcs = new PropertyChangeSupport(this);
	}
	
	/**
	 * Creates a new troop for player and on a tile position.
	 * @param player Owner of this troop.
	 * @param position Position on the gameboard for this troop.
	 */
	public Troop(IPlayer player, ITile position){
		this();
		this.player = player;
		this.position = position;
		position.addTroop(this);
	}
	
	@Override
	public IPlayer getPlayer(){
		return player;
	}
	@Override
	public boolean isDefeated(){
		
		boolean defeated = true;
		
		for (ISoldier soldier : getSoldiers()){
			
			if (getAmount(soldier) > 0){
				defeated = false;
			}
		}
		
		return defeated;
	}
	
	@Override
	public ITile getPosition() {
		return position;
	}
	

	@Override
	public int remove(ISoldier soldier, Integer amount){
		
		int amountRemoved = Math.min(amount, getAmount(soldier));
		
		add(soldier, -amountRemoved);
		
		if(map.get(soldier) == 0){
			map.remove(soldier);
		}
		
		return amountRemoved;
	}
	
	
	@Override
	public void add(ISoldier soldier, Integer amount){
		if (amount != 0){
			map.put(soldier, getAmount(soldier) + amount);
		}				
	}
	
	@Override
	public boolean contains(ISoldier s){
		return map.containsKey(s);
	}

	
	@Override
	public void moveTo(ITile newPosition){
		position.removeTroop(this);
		newPosition.addTroop(this);
		pcs.firePropertyChange("movement", position, position = newPosition);
	}
	
	@Override
	public int getAmount(ISoldier s){
		return map.containsKey(s) ?  map.get(s): 0;
	}
	
	@Override
	public Set<ISoldier> getSoldiers(){		
		return map.keySet();
	}

	@Override
	public void addPropertyChangeListener(PropertyChangeListener observer) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removePropertyChangeListener(PropertyChangeListener observer) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public IType getSoldierType() {
		return soldierType;
	}

	@Override
	public void merge(ITroop t) {
		for (ISoldier soldier : map.keySet()){			
			t.add(soldier, getAmount(soldier));			
		}
	
	map.clear();
		
	}	
}
